package com.rp.dao.local;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.rp.dao.IProdutoEstabelecimentoDAO;
import com.rp.dao.ResultSetProcessor;
import com.rp.model.ProdutoEstabelecimento;
import com.rp.view.ItemListaPesquisaProduto;

public class ProdutoEstabelecimentoLDAO implements IProdutoEstabelecimentoDAO {

    private Context context;
    private static final String DB_NAME = "DB_RP";

    public ProdutoEstabelecimentoLDAO(Context context) {
	this.context = context;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.rp.dao.local.IProdutoEstabelecimentoDAO#criarTabela1()
     */
    @Override
    public void criarTabela1() throws Throwable {
	SQLiteDatabase BancoDados = null;
	try {
	    BancoDados = context.openOrCreateDatabase(DB_NAME,
		    Context.MODE_WORLD_READABLE, null);
	    BancoDados
		    .execSQL("CREATE TABLE IF NOT EXISTS produto_estabelecimento ("
			    + "ean_produto INTEGER, cnpj_estabelecimento INTEGER, valor REAL, data_alteracao INTEGER);");
	} finally {
	    BancoDados.close();
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.rp.dao.local.IProdutoEstabelecimentoDAO#insereValor(long, long,
     * double, long)
     */
    @Override
    public void insereValor(long eanProduto, long cnpjEstabelecimento,
	    float valor, long date) throws Throwable {

	SQLiteDatabase BancoDados = null;
	try {
	    BancoDados = context.openOrCreateDatabase(DB_NAME,
		    Context.MODE_WORLD_READABLE, null);
	    BancoDados
		    .execSQL("INSERT INTO produto_estabelecimento (ean_produto,cnpj_estabelecimento,valor,data_alteracao) VALUES("
			    + eanProduto
			    + ","
			    + cnpjEstabelecimento
			    + ","
			    + valor + "," + date + ");");
	} finally {
	    BancoDados.close();
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.rp.dao.local.IProdutoEstabelecimentoDAO#atualizaValor(long,
     * double)
     */
    @Override
    public void atualizaValor(long eanProduto, long cnpjEstabelecimento,
	    float valor, long date) throws Throwable {
	SQLiteDatabase BancoDados = null;
	try {
	    BancoDados = context.openOrCreateDatabase(DB_NAME,
		    Context.MODE_WORLD_READABLE, null);
	    BancoDados.execSQL("UPDATE produto_estabelecimento SET valor = "
		    + valor + ", data_alteracao = " + date
		    + " WHERE ean_produto = " + eanProduto
		    + " AND cnpj_estabelecimento = " + cnpjEstabelecimento
		    + ";");
	} finally {
	    BancoDados.close();
	}
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.rp.dao.local.IProdutoEstabelecimentoDAO#buscaPorProduto(long)
     */
    @Override
    public List<ItemListaPesquisaProduto> buscaPorProduto(long eanProduto)
	    throws Throwable {
	List<ItemListaPesquisaProduto> data = new ArrayList<ItemListaPesquisaProduto>();
	SQLiteDatabase BancoDados = null;
	try {
	    BancoDados = context.openOrCreateDatabase(DB_NAME,
		    Context.MODE_WORLD_READABLE, null);
	    Cursor cursor = BancoDados
		    .rawQuery(
			    "SELECT E.NOME nome_estabelecimento, E.endereco endereco, PE.valor valor, PE.data_alteracao data_alteracao FROM produto_estabelecimento PE"
				    + " LEFT JOIN estabelecimento E ON PE.cnpj_estabelecimento = E.cnpj "
				    + " LEFT JOIN produto P ON  P.ean = PE.ean_produto WHERE PE.ean_produto = "
				    + eanProduto + " ORDER BY valor;", null);
	    try {
		while (cursor.moveToNext()) {
		    String nome = cursor.getString(0);
		    String endereco = cursor.getString(1);
		    double valor = cursor.getDouble(2);
		    long data_alteracao = cursor.getLong(3);
		    ItemListaPesquisaProduto item = new ItemListaPesquisaProduto(
			    nome, endereco, valor, new Date(data_alteracao));
		    data.add(item);
		}
	    } finally {
		cursor.close();
	    }
	} finally {
	    BancoDados.close();
	}
	return data;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.rp.dao.local.IProdutoEstabelecimentoDAO#buscaPorProdutoEstabelecimento
     * (long, long)
     */
    @Override
    public ItemListaPesquisaProduto buscaPorProdutoEstabelecimento(
	    long produto, long estabelecimento) throws Throwable {
	ItemListaPesquisaProduto data = null;
	SQLiteDatabase BancoDados = context.openOrCreateDatabase(DB_NAME,
		Context.MODE_WORLD_READABLE, null);
	try {
	    Cursor resultSet = BancoDados
		    .rawQuery(
			    "SELECT E.NOME nome_estabelecimento, E.endereco endereco, PE.valor valor, PE.data_alteracao data_alteracao FROM produto_estabelecimento PE"
				    + " LEFT JOIN estabelecimento E ON PE.cnpj_estabelecimento = E.cnpj"
				    + " LEFT JOIN produto P ON  P.ean  = PE.ean_produto WHERE PE.ean_produto = "
				    + produto
				    + " AND PE.cnpj_estabelecimento = "
				    + estabelecimento + ";", null);
	    try {
		if (resultSet.moveToNext()) {
		    String nome = resultSet.getString(0);
		    String endereco = resultSet.getString(1);
		    double valor = resultSet.getDouble(2);
		    long data_alteracao = resultSet.getLong(3);
		    data = new ItemListaPesquisaProduto(nome, endereco, valor,
			    new Date(data_alteracao));
		}
	    } finally {
		resultSet.close();
	    }
	} finally {
	    if (BancoDados != null) {
		BancoDados.close();
	    }
	}
	return data;
    }

    @Override
    public long count(Calendar data) throws Throwable {
	SQLiteDatabase BancoDados = context.openOrCreateDatabase(DB_NAME,
		Context.MODE_WORLD_READABLE, null);
	long count = 0;
	try {
	    Cursor resultSet = BancoDados.rawQuery(
		    "SELECT count(*) FROM produto_estabelecimento WHERE data_alteracao > "
			    + data.getTimeInMillis() + ";", null);
	    try {
		if (resultSet.moveToNext()) {
		    count = resultSet.getLong(0);// id
		}
	    } finally {
		resultSet.close();
	    }
	} finally {
	    if (BancoDados != null) {
		BancoDados.close();
	    }
	}
	return count;
    }

    public ResultSetProcessor<ProdutoEstabelecimento> getPendencias(
	    Calendar data) {
	final SQLiteDatabase BancoDados = context.openOrCreateDatabase(DB_NAME,
		Context.MODE_WORLD_READABLE, null);
	final Cursor resultSet = BancoDados.rawQuery(
		"SELECT * FROM produto_estabelecimento WHERE data_alteracao > "
			+ data.getTimeInMillis() + ";", null);
	return new ResultSetProcessor<ProdutoEstabelecimento>() {
	    @Override
	    public ProdutoEstabelecimento process() throws Throwable {
		ProdutoEstabelecimento produtoEstabelecimento = null;
		if (resultSet.moveToNext()) {
		    long produto = resultSet.getLong(0);// id
		    long estabelecimento = resultSet.getLong(1);// id
		    float valor = resultSet.getFloat(2);// id
		    long dataAlteracao = resultSet.getLong(3);// id
		    produtoEstabelecimento = new ProdutoEstabelecimento(
			    produto, estabelecimento, valor, dataAlteracao);
		} else {
		    resultSet.close();
		    BancoDados.close();
		}
		return produtoEstabelecimento;
	    }
	};
    }
}
